package com.fds.system.config;

import com.alibaba.fastjson.JSONObject;
import com.fds.system.model.LoginUser;
import com.fds.system.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * @author: fds
 * @description: jwt-token过滤器
 */
@Component
@Slf4j
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private SecurityProperties securityProperties;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String authToken = request.getHeader("Authorization");
        response.setCharacterEncoding("utf-8");
        if (StringUtils.isEmpty(authToken)) {
            // 用户未登录
            filterChain.doFilter(request, response);
            return;
        }
        // 获取redis中的token信息
        if (!redisUtil.hasKey(authToken)) {
            // 用户未登录
            filterChain.doFilter(request, response);
            return;
        }

        Object data = redisUtil.get(authToken);
        if (null == data) {
            // 用户未登录
            filterChain.doFilter(request, response);
            return;
        }

        // 获取缓存中的信息(根据自己的业务进行拓展)
        LoginUser loginUser = JSONObject.parseObject(data.toString(), LoginUser.class);
        // 设置权限
        loginUser.setSystemAuthorities();
        // 从tokenInfo中取出用户信息
        // 更新token过期时间
        redisUtil.setKeyExpire(authToken, securityProperties.getExpirationMilliSeconds());
        // 将信息交给security
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
        authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        filterChain.doFilter(request, response);
    }
}